package com.lyj.ms.service.impl;

import com.lyj.ms.service.MsService;
import com.lyj.ms.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 秒杀接口实现类
 * @author:liyajie
 * @createTime:2021/12/16 14:56
 * @version:1.0
 */
@Service
@Slf4j
public class MsServiceImpl implements MsService {

    @Autowired
    RedisUtils redisUtils;

    //总库存
    private long nKuCuen = 0;
    //商品key名字
    private String shangpingKey = "computer_key";
    //获取锁的超时时间 秒
    private int timeout = 30 * 1000;

    public String qiang(String b) {
        //用户开抢时间
        long startTime = System.currentTimeMillis();

        //未抢到的情况下，30秒内继续获取锁
        while ((startTime + timeout) >= System.currentTimeMillis()) {
            //商品是否剩余
            if (nKuCuen <= 0) {
                break;
            }
            if (redisUtils.setnx(shangpingKey, b)) {
                //用户b拿到锁
                log.info("用户{}拿到锁...", b);
                try {
                    //商品是否剩余
                    if (nKuCuen <= 0) {
                        break;
                    }

                    //模拟生成订单耗时操作，方便查看：神器-50 多次获取锁记录
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    //抢购成功，商品递减，记录用户
                    nKuCuen -= 1;

                    //抢单成功跳出
                    log.info("用户{}抢单成功跳出...所剩库存：{}", b, nKuCuen);

                    return b + "抢单成功，所剩库存：" + nKuCuen;
                } finally {
                    log.info("用户{}释放锁...", b);
                    //释放锁
                    redisUtils.delnx(shangpingKey, b);
                }
            } else {
                // 用户b没拿到锁，在超时范围内继续请求锁，不需要处理
                /*if (b.equals("神器-50") || b.equals("神器-69")) {
                    log.info("用户{}等待获取锁...", b);
                }*/
            }
        }
        return "";
    }
}
